/**
 * Created by PanJiaChen on 16/11/18.
 */

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
      time = parseInt(time)
    }
    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
    let value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value ] }
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = url.split('?')[1]
  if (!search) {
    return {}
  }
  return JSON.parse(
    '{"' +
      decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"')
        .replace(/\+/g, ' ') +
      '"}'
  )
}

export function isEmpty(val) {
  return typeof val === 'undefined' || val === null || val === ''
}

export function getRandomString(num) { // 生成指定长度的随机字符串
  var r = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0']
  var s = []
  var l = r.length
  while (s.length <= num) {
    const v = r[Math.floor(Math.random() * l)]
    s.push(Math.random() > 0.5 ? v : v.toUpperCase())
  }
  return s.join('')
}

export function nest2Flat(data, keys = {}) { // 嵌套结构转成父子关系的数组
  const mergeKeys = {
    id: 'id', // 数据id
    pid: 'parentId', // 数据父id
    children: 'children', // 子节点名
    ...keys
  }
  const ret = []

  function settle(data, pid) {
    data.forEach(item => {
      const childs = item[mergeKeys.children]
      const id = getRandomString(32)
      if (childs && childs.length > 0) {
        settle(childs, id)
      }

      ret.push({
        [mergeKeys.id]: id,
        [mergeKeys.pid]: pid,
        ...item
      })
    })
  }

  settle(data)
  return ret
}

export function flat2Nest(data, keys = {}) { // 父子id关系的数组转成嵌套结构
  const mergeKeys = {
    id: 'id', // 数据id
    pid: 'parentId', // 数据父id
    children: 'children', // 子节点名
    ...keys
  }

  function findChilds(pid) {
    if (isEmpty(pid)) {
      return data.filter(item => isEmpty(item[mergeKeys.pid]))
    }
    return data.filter(item => item[mergeKeys.pid] === pid)
  }

  function setChilds(arr) {
    arr.forEach(item => {
      const childs = findChilds(item[mergeKeys.id])
      if (childs.length > 0) {
        setChilds(childs)
        item[mergeKeys.children] = childs
      }

      item._signature = getRandomString(32) // 添加唯一的键,用于渲染时提高性能
      item._isLeaf = childs.length === 0 // 是否为叶子节点
    })
  }
  const result = findChilds()
  setChilds(result)
  return result
}
